#include <stdio.h>
#include <stdlib.h>
#include "queue.h"
#include "aos/kernel.h"

unsigned int cnt = 0;
unsigned int cnt_ok = 0;

//unsigned int node_num_ = 0;
//unsigned int link_size_ = 0;

int QueueInit(LinkQueue *Q, int node_num, int link_size)
{
	char * queue_head = NULL;
	int i;
	Q->link_size_ = link_size;
	Q->node_num_ = node_num;
	
	queue_head = (char *)aos_calloc(1, Q->link_size_*Q->node_num_);
	if(queue_head == NULL)
	{
		printf("queue malloc error!\n");
		return -1;
	}
	///////
	Q->headptr = queue_head;//malloc head pointer


	Q->link = aos_malloc(Q->node_num_ * sizeof(LinkNode));
	for(i=0;i<Q->node_num_;i++)
	{
		Q->link[i].buf = (unsigned char *)(queue_head + i * Q->link_size_);
		Q->link[i].dirty = 0;
		Q->link[i].len = 0;
	}

    Q->front = Q->rear=0;
    Q->count = 0;
	return 0;
}


void QueueDestroy(LinkQueue *Q)
{
	int i;
	if(Q->headptr)
	{
		free(Q->headptr);
		Q->headptr = NULL;
	}
	//////
	for(i=0;i<Q->node_num_;i++)
	{
		Q->link[i].buf = NULL;
		Q->link[i].dirty = 0;
		Q->link[i].len = 0;
	}
}

int QueueFull(LinkQueue *Q)
{
	return (Q->front==Q->rear)&&(Q->count==Q->node_num_);
}

int QueueEmpty(LinkQueue *Q)
{
	return (Q->front==Q->rear)&&(Q->count==0);
}


LinkNode* GetEmptyNode(LinkQueue *Q)
{
	if(QueueFull(Q))
   	{
		return NULL;
   	}
	///////
	if(Q->link[Q->rear].dirty == 0)
	{
		return &(Q->link[Q->rear]);
	}
	//////
	return NULL;
}

LinkNode* GetFullNode(LinkQueue *Q)
{
    if(QueueEmpty(Q))
    {
		return NULL;
    }

	///////
	if(Q->link[Q->front].dirty == 1)
	{
		return &(Q->link[Q->front]);
	}
	//////
	return NULL;
}

int QueueSendFull(LinkQueue *Q, LinkNode *Node, int len)
{
	////
	Node->dirty = 1;
	Node->len = len;
	Q->rear = (Q->rear+1)%Q->node_num_;
	Q->count++;
	return 0;
}

int QueueSendEmpty(LinkQueue *Q, LinkNode *Node, int len)
{
	Node->dirty = 0;
	Q->front = (Q->front+1) % Q->node_num_;
	Q->count--; 

	return 0;
}

/*
int QueueFront(LinkQueue *Q)
{
        assert(!QueueEmpty(Q));
        return Q->data[Q->front];
}
*/
